1 module directx.x3daudio;
2 
3 version(Windows):
4 version(X3DAudio):
5 
6 import directx.win32;
7 
8 // test if type defined
9 static if ( !__traits(compiles, D3DVECTOR.sizeof) )
10 {
11 	alias D3DVECTOR = float[3];
12 }
13 
14 // speaker geometry configuration flags, specifies assignment of channels to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask
15 alias _SPEAKER_POSITIONS_ = int;
16 enum : _SPEAKER_POSITIONS_
17 {
18     SPEAKER_FRONT_LEFT            = 0x00000001,
19     SPEAKER_FRONT_RIGHT           = 0x00000002,
20     SPEAKER_FRONT_CENTER          = 0x00000004,
21     SPEAKER_LOW_FREQUENCY         = 0x00000008,
22     SPEAKER_BACK_LEFT             = 0x00000010,
23     SPEAKER_BACK_RIGHT            = 0x00000020,
24     SPEAKER_FRONT_LEFT_OF_CENTER  = 0x00000040,
25     SPEAKER_FRONT_RIGHT_OF_CENTER = 0x00000080,
26     SPEAKER_BACK_CENTER           = 0x00000100,
27     SPEAKER_SIDE_LEFT             = 0x00000200,
28     SPEAKER_SIDE_RIGHT            = 0x00000400,
29     SPEAKER_TOP_CENTER            = 0x00000800,
30     SPEAKER_TOP_FRONT_LEFT        = 0x00001000,
31     SPEAKER_TOP_FRONT_CENTER      = 0x00002000,
32     SPEAKER_TOP_FRONT_RIGHT       = 0x00004000,
33     SPEAKER_TOP_BACK_LEFT         = 0x00008000,
34     SPEAKER_TOP_BACK_CENTER       = 0x00010000,
35     SPEAKER_TOP_BACK_RIGHT        = 0x00020000,
36     SPEAKER_RESERVED              = 0x7FFC0000, // bit mask locations reserved for future use
37     SPEAKER_ALL                   = 0x80000000, // used to specify that any possible permutation of speaker configurations
38 }
39 
40 // standard speaker geometry configurations, used with X3DAudioInitialize
41 enum
42 {
43     SPEAKER_MONO             = SPEAKER_FRONT_CENTER,
44     SPEAKER_STEREO           = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT),
45     SPEAKER_2POINT1          = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY),
46     SPEAKER_SURROUND         = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER),
47     SPEAKER_QUAD             = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
48     SPEAKER_4POINT1          = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
49     SPEAKER_5POINT1          = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
50     SPEAKER_7POINT1          = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER),
51     SPEAKER_5POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT  | SPEAKER_SIDE_RIGHT),
52     SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT  | SPEAKER_SIDE_RIGHT),
53 }
54 
55 // Xbox360 speaker geometry configuration, used with X3DAudioInitialize
56 version(XBOX)
57 	alias SPEAKER_XBOX = SPEAKER_5POINT1;
58 
59 
60 
61 // size of instance handle in bytes
62 enum X3DAUDIO_HANDLE_BYTESIZE = 20;
63 
64 // float math constants
65 enum X3DAUDIO_PI  = 3.141592654f;
66 enum X3DAUDIO_2PI = 6.283185307f;
67 
68 // speed of sound in meters per second for dry air at approximately 20C, used with X3DAudioInitialize
69 enum X3DAUDIO_SPEED_OF_SOUND = 343.5f;
70 
71 // calculation control flags, used with X3DAudioCalculate
72 enum {
73     X3DAUDIO_CALCULATE_MATRIX          = 0x00000001, // enable matrix coefficient table calculation
74     X3DAUDIO_CALCULATE_DELAY           = 0x00000002, // enable delay time array calculation (stereo final mix only)
75     X3DAUDIO_CALCULATE_LPF_DIRECT      = 0x00000004, // enable LPF direct-path coefficient calculation
76     X3DAUDIO_CALCULATE_LPF_REVERB      = 0x00000008, // enable LPF reverb-path coefficient calculation
77     X3DAUDIO_CALCULATE_REVERB          = 0x00000010, // enable reverb send level calculation
78     X3DAUDIO_CALCULATE_DOPPLER         = 0x00000020, // enable doppler shift factor calculation
79     X3DAUDIO_CALCULATE_EMITTER_ANGLE   = 0x00000040, // enable emitter-to-listener interior angle calculation
80 
81     X3DAUDIO_CALCULATE_ZEROCENTER      = 0x00010000, // do not position to front center speaker, signal positioned to remaining speakers instead, front center destination channel will be zero in returned matrix coefficient table, valid only for matrix calculations with final mix formats that have a front center channel
82     X3DAUDIO_CALCULATE_REDIRECT_TO_LFE = 0x00020000, // apply equal mix of all source channels to LFE destination channel, valid only for matrix calculations with sources that have no LFE channel and final mix formats that have an LFE channel
83 }
84 
85 
86 //--------------<D-A-T-A---T-Y-P-E-S>---------------------------------------//
87 align(1): // set packing alignment to ensure consistency across arbitrary build environments
88 
89 
90 // primitive types
91 alias FLOAT32 = float; // 32-bit IEEE float
92 alias X3DAUDIO_VECTOR = D3DVECTOR; // float 3D vector
93 
94 // instance handle of precalculated constants
95 alias BYTE[X3DAUDIO_HANDLE_BYTESIZE] X3DAUDIO_HANDLE;
96 
97 
98 // Distance curve point:
99 // Defines a DSP setting at a given normalized distance.
100 struct X3DAUDIO_DISTANCE_CURVE_POINT
101 {
102     FLOAT32 Distance;   // normalized distance, must be within [0.0f, 1.0f]
103     FLOAT32 DSPSetting; // DSP setting
104 }
105 alias LPX3DAUDIO_DISTANCE_CURVE_POINT = X3DAUDIO_DISTANCE_CURVE_POINT*;
106 
107 // Distance curve:
108 // A piecewise curve made up of linear segments used to
109 // define DSP behaviour with respect to normalized distance.
110 //
111 // Note that curve point distances are normalized within [0.0f, 1.0f].
112 // X3DAUDIO_EMITTER.CurveDistanceScaler must be used to scale the
113 // normalized distances to user-defined world units.
114 // For distances beyond CurveDistanceScaler * 1.0f,
115 // pPoints[PointCount-1].DSPSetting is used as the DSP setting.
116 //
117 // All distance curve spans must be such that:
118 //      pPoints[k-1].DSPSetting + ((pPoints[k].DSPSetting-pPoints[k-1].DSPSetting) / (pPoints[k].Distance-pPoints[k-1].Distance)) * (pPoints[k].Distance-pPoints[k-1].Distance) != NAN or infinite values
119 // For all points in the distance curve where 1 <= k < PointCount.
120 struct X3DAUDIO_DISTANCE_CURVE
121 {
122     X3DAUDIO_DISTANCE_CURVE_POINT* pPoints;    // distance curve point array, must have at least PointCount elements with no duplicates and be sorted in ascending order with respect to Distance
123     UINT32                         PointCount; // number of distance curve points, must be >= 2 as all distance curves must have at least two endpoints, defining DSP settings at 0.0f and 1.0f normalized distance
124 }
125 alias LPX3DAUDIO_DISTANCE_CURVE = X3DAUDIO_DISTANCE_CURVE*;
126 enum : X3DAUDIO_DISTANCE_CURVE_POINT[2]
127 {
128 	X3DAudioDefault_LinearCurvePoints = [ X3DAUDIO_DISTANCE_CURVE_POINT(0.0f, 1.0f), X3DAUDIO_DISTANCE_CURVE_POINT(1.0f, 0.0f) ],
129 }
130 enum : X3DAUDIO_DISTANCE_CURVE
131 {
132 	X3DAudioDefault_LinearCurve = X3DAUDIO_DISTANCE_CURVE( X3DAudioDefault_LinearCurvePoints.ptr, 2 ),
133 }
134 
135 // Cone:
136 // Specifies directionality for a listener or single-channel emitter by
137 // modifying DSP behaviour with respect to its front orientation.
138 // This is modeled using two sound cones: an inner cone and an outer cone.
139 // On/within the inner cone, DSP settings are scaled by the inner values.
140 // On/beyond the outer cone, DSP settings are scaled by the outer values.
141 // If on both the cones, DSP settings are scaled by the inner values only.
142 // Between the two cones, the scaler is linearly interpolated between the
143 // inner and outer values.  Set both cone angles to 0 or X3DAUDIO_2PI for
144 // omnidirectionality using only the outer or inner values respectively.
145 struct X3DAUDIO_CONE
146 {
147     FLOAT32 InnerAngle; // inner cone angle in radians, must be within [0.0f, X3DAUDIO_2PI]
148     FLOAT32 OuterAngle; // outer cone angle in radians, must be within [InnerAngle, X3DAUDIO_2PI]
149 
150     FLOAT32 InnerVolume; // volume level scaler on/within inner cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used
151     FLOAT32 OuterVolume; // volume level scaler on/beyond outer cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used
152     FLOAT32 InnerLPF;    // LPF (both direct and reverb paths) coefficient subtrahend on/within inner cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used
153     FLOAT32 OuterLPF;    // LPF (both direct and reverb paths) coefficient subtrahend on/beyond outer cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used
154     FLOAT32 InnerReverb; // reverb send level scaler on/within inner cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used
155     FLOAT32 OuterReverb; // reverb send level scaler on/beyond outer cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used
156 }
157 alias LPX3DAUDIO_CONE = X3DAUDIO_CONE*;
158 enum : X3DAUDIO_CONE
159 {
160 	X3DAudioDefault_DirectionalCone = X3DAUDIO_CONE( X3DAUDIO_PI/2, X3DAUDIO_PI, 1.0f, 0.708f, 0.0f, 0.25f, 0.708f, 1.0f ),
161 }
162 
163 
164 // Listener:
165 // Defines a point of 3D audio reception.
166 //
167 // The cone is directed by the listener's front orientation.
168 struct X3DAUDIO_LISTENER
169 {
170     X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for matrix and delay calculations or listeners with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used
171     X3DAUDIO_VECTOR OrientTop;   // orientation of top direction, used only for matrix and delay calculations, must be orthonormal with OrientFront when used
172 
173     X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity
174     X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position
175 
176     X3DAUDIO_CONE* pCone; // sound cone, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality
177 } 
178 alias LPX3DAUDIO_LISTENER = X3DAUDIO_LISTENER*;
179 
180 // Emitter:
181 // Defines a 3D audio source, divided into two classifications:
182 //
183 // Single-point -- For use with single-channel sounds.
184 //                 Positioned at the emitter base, i.e. the channel radius
185 //                 and azimuth are ignored if the number of channels == 1.
186 //
187 //                 May be omnidirectional or directional using a cone.
188 //                 The cone originates from the emitter base position,
189 //                 and is directed by the emitter's front orientation.
190 //
191 // Multi-point  -- For use with multi-channel sounds.
192 //                 Each non-LFE channel is positioned using an
193 //                 azimuth along the channel radius with respect to the
194 //                 front orientation vector in the plane orthogonal to the
195 //                 top orientation vector.  An azimuth of X3DAUDIO_2PI
196 //                 specifies a channel is an LFE.  Such channels are
197 //                 positioned at the emitter base and are calculated
198 //                 with respect to pLFECurve only, never pVolumeCurve.
199 //
200 //                 Multi-point emitters are always omnidirectional,
201 //                 i.e. the cone is ignored if the number of channels > 1.
202 //
203 // Note that many properties are shared among all channel points,
204 // locking certain behaviour with respect to the emitter base position.
205 // For example, doppler shift is always calculated with respect to the
206 // emitter base position and so is constant for all its channel points.
207 // Distance curve calculations are also with respect to the emitter base
208 // position, with the curves being calculated independently of each other.
209 // For instance, volume and LFE calculations do not affect one another.
210 struct X3DAUDIO_EMITTER
211 {
212     X3DAUDIO_CONE* pCone; // sound cone, used only with single-channel emitters for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality
213     X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for emitter angle calculations or with multi-channel emitters for matrix calculations or single-channel emitters with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used
214     X3DAUDIO_VECTOR OrientTop;   // orientation of top direction, used only with multi-channel emitters for matrix calculations, must be orthonormal with OrientFront when used
215 
216     X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity
217     X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position
218 
219     FLOAT32 InnerRadius;      // inner radius, must be within [0.0f, FLT_MAX]
220     FLOAT32 InnerRadiusAngle; // inner radius angle, must be within [0.0f, X3DAUDIO_PI/4.0)
221 
222     UINT32 ChannelCount;       // number of sound channels, must be > 0
223     FLOAT32 ChannelRadius;     // channel radius, used only with multi-channel emitters for matrix calculations, must be >= 0.0f when used
224     FLOAT32* pChannelAzimuths; // channel azimuth array, used only with multi-channel emitters for matrix calculations, contains positions of each channel expressed in radians along the channel radius with respect to the front orientation vector in the plane orthogonal to the top orientation vector, or X3DAUDIO_2PI to specify an LFE channel, must have at least ChannelCount elements, all within [0.0f, X3DAUDIO_2PI] when used
225 
226     X3DAUDIO_DISTANCE_CURVE* pVolumeCurve;    // volume level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation
227     X3DAUDIO_DISTANCE_CURVE* pLFECurve;       // LFE level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation
228     X3DAUDIO_DISTANCE_CURVE* pLPFDirectCurve; // LPF direct-path coefficient distance curve, used only for LPF direct-path calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.75f]
229     X3DAUDIO_DISTANCE_CURVE* pLPFReverbCurve; // LPF reverb-path coefficient distance curve, used only for LPF reverb-path calculations, NULL specifies the default curve: [0.0f,0.75f], [1.0f,0.75f]
230     X3DAUDIO_DISTANCE_CURVE* pReverbCurve;    // reverb send level distance curve, used only for reverb calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.0f]
231 
232     FLOAT32 CurveDistanceScaler; // curve distance scaler, used to scale normalized distance curves to user-defined world units and/or exaggerate their effect, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, must be within [FLT_MIN, FLT_MAX] when used
233     FLOAT32 DopplerScaler;       // doppler shift scaler, used to exaggerate doppler shift effect, used only for doppler calculations, must be within [0.0f, FLT_MAX] when used
234 }
235 alias LPX3DAUDIO_EMITTER = X3DAUDIO_EMITTER*;
236 
237 
238 // DSP settings:
239 // Receives results from a call to X3DAudioCalculate to be sent
240 // to the low-level audio rendering API for 3D signal processing.
241 //
242 // The user is responsible for allocating the matrix coefficient table,
243 // delay time array, and initializing the channel counts when used.
244 struct X3DAUDIO_DSP_SETTINGS
245 {
246     FLOAT32* pMatrixCoefficients; // [inout] matrix coefficient table, receives an array representing the volume level used to send from source channel S to destination channel D, stored as pMatrixCoefficients[SrcChannelCount * D + S], must have at least SrcChannelCount*DstChannelCount elements
247     FLOAT32* pDelayTimes;         // [inout] delay time array, receives delays for each destination channel in milliseconds, must have at least DstChannelCount elements (stereo final mix only)
248     UINT32 SrcChannelCount;       // [in] number of source channels, must equal number of channels in respective emitter
249     UINT32 DstChannelCount;       // [in] number of destination channels, must equal number of channels of the final mix
250 
251     FLOAT32 LPFDirectCoefficient; // [out] LPF direct-path coefficient
252     FLOAT32 LPFReverbCoefficient; // [out] LPF reverb-path coefficient
253     FLOAT32 ReverbLevel; // [out] reverb send level
254     FLOAT32 DopplerFactor; // [out] doppler shift factor, scales resampler ratio for doppler shift effect, where the effective frequency = DopplerFactor * original frequency
255     FLOAT32 EmitterToListenerAngle; // [out] emitter-to-listener interior angle, expressed in radians with respect to the emitter's front orientation
256 
257     FLOAT32 EmitterToListenerDistance; // [out] distance in user-defined world units from the emitter base to listener position, always calculated
258     FLOAT32 EmitterVelocityComponent; // [out] component of emitter velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler
259     FLOAT32 ListenerVelocityComponent; // [out] component of listener velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler
260 }
261 alias LPX3DAUDIO_DSP_SETTINGS = X3DAUDIO_DSP_SETTINGS*;
262 
263 
264 
265 //--------------<F-U-N-C-T-I-O-N-S>-----------------------------------------//
266 // initializes instance handle
267 extern(Windows) void X3DAudioInitialize (UINT32 SpeakerChannelMask, FLOAT32 SpeedOfSound, /*out*/ X3DAUDIO_HANDLE* Instance);
268 
269 // calculates DSP settings with respect to 3D parameters
270 extern(Windows) void X3DAudioCalculate (const(X3DAUDIO_HANDLE) Instance, const(X3DAUDIO_LISTENER)* pListener, const(X3DAUDIO_EMITTER)* pEmitter, UINT32 Flags, /*inout*/X3DAUDIO_DSP_SETTINGS* pDSPSettings);
271 
272 //---------------------------------<-EOF->----------------------------------//